﻿using UnityEngine;

namespace Core.Touch
{
    public class TouchInput : Component, IAwake, IUpdate
    {
        public float ReactionDistance = 1f;

        private Vector3 m_down_pos;
        private Vector3 m_curr_pos;
        private Vector3 m_last_pos;
        private bool IsDrag;
        private bool IsDown;

        public EDir4 CurrDir { get; private set; } = EDir4.Invalid;

        public bool IsDir(EDir4 dir)
        {
            return dir == CurrDir;
        }

        public void Awake()
        {
            IsDown = false;
            IsDrag = false;
        }

        public override void Dispose()
        {
            if (IsDisposed) return;
            base.Dispose();

            IsDown = false;
            IsDrag = false;

            //IsVertical = true;
        }

        public void Update()
        {
            CurrDir = EDir4.Invalid;

            #region KeyBoard

            if (Input.GetKeyUp(KeyCode.W) || Input.GetKeyUp(KeyCode.UpArrow))
            {
                CurrDir = EDir4.Up;
                OnKeyClickAutoDrag();
                return;
            }
            if (Input.GetKeyUp(KeyCode.S) || Input.GetKeyUp(KeyCode.DownArrow))
            {
                CurrDir = EDir4.Down;
                OnKeyClickAutoDrag();
                return;
            }
            if (Input.GetKeyUp(KeyCode.A) || Input.GetKeyUp(KeyCode.LeftArrow))
            {
                CurrDir = EDir4.Left;
                OnKeyClickAutoDrag();
                return;
            }
            if (Input.GetKeyUp(KeyCode.D) || Input.GetKeyUp(KeyCode.RightArrow))
            {
                CurrDir = EDir4.Right;
                OnKeyClickAutoDrag();
                return;
            }

            #endregion

            #region Touch Screen
            if (IsDown == false)
            {
                if (Input.GetMouseButtonDown(0))
                {
                    OnDown();
                }
                return;
            }

            if (Input.GetMouseButtonUp(0))
            {
                OnUp();
                return;
            }

            m_curr_pos = Input.mousePosition;
            if (IsDrag == false)
            {
                if (Vector3.Distance(m_curr_pos, m_down_pos) > ReactionDistance)
                {
                    OnBeginDrag();
                }
            }
            else
            {
                if (m_curr_pos != m_last_pos)
                {
                    OnDrag();
                }
            }
            #endregion
        }

        private void OnDown()
        {
            m_down_pos = Input.mousePosition;
            m_curr_pos = m_down_pos;
            m_last_pos = m_down_pos;
            IsDown = true;
        }

        private void OnUp()
        {
            if (!IsDown)
            {
                return;
            }

            if (IsDrag == false)
            {
                OnClick();
            }
            else
            {
                OnEndDrag();
            }
            IsDrag = false;
            IsDown = false;
        }

        private void OnBeginDrag()
        {
            var dir = m_curr_pos - m_down_pos;

            var angle = Utils.Math.GetAngle(dir, new Vector3(0, 1, 0));

            CurrDir = Utils.Dir.Get4(angle);

            if (CurrDir == EDir4.Invalid)
            {
                return;
            }

            IsDrag = true;

            OnDrag();
        }

        private void OnDrag()
        {
        }

        private void OnEndDrag()
        {
        }

        private void OnClick()
        {
        }

        private void OnKeyClickAutoDrag()
        {
        }

    }
}
